/*
 ------------------------------------------------------------------------------
 Copyright (C) 2006-2007 Team Blur.

 This file is part of the Quantum Engine source code.

 The Quantum Engine source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quantum Engine source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quantum Engine source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


#ifndef __SERVER_H__
#define __SERVER_H__


#include "../core/core_main.h"
#include "../game/server/sg_public.h"
#include "../collision/cm_public.h"
#include "../editor/ed_public.h"
#include "../network/net_main.h"

#define HEARTBEAT_TIMEOUT				300000

// MAX_CHALLENGES is made large to prevent denial of service attacks that could
// cycle all of them out before legitimate users connected
#define	MAX_CHALLENGES					1024

// Client states
typedef enum {
	CS_FREE,									// Can be reused for a new connection
	CS_ZOMBIE,									// Client has been disconnected, but don't reuse connection yet
	CS_CONNECTED,								// Has been assigned to a client_t, but no game state yet
	CS_PRIMED,									// Game state has been sent, but client hasn't sent a user command
	CS_ACTIVE									// Client is fully in game
} clientState_t;

typedef struct {
	clientState_t			state;				// Client status

	int						clientNum;

	int						serverId;			// To detect if a server state needs to be (re)sent

	// Last user command executed
	userCmd_t				lastUserCmd;

	// User information
	char					userInfo[MAX_STRING_LENGTH];
	char					name[MAX_NAME_LENGTH];
	// Connection information
	ENetPeer				*peer;//connection to the client
} client_t;

// The serverActive_t structure is wiped completely at every level change
typedef struct {
	int						serverId;

	int						frameMsec;
	int						timeResidual;

	// Pack checksums for auto-downloading and pure validation
	ulong					packChecksums[MAX_PACK_FILES];
} serverActive_t;

// The serverStatic_t structure is wiped only when the server is shutting down
typedef struct {
	bool					initialized;		// Sever initialization has completed

	int						time;				// Will be strictly increasing across level changes

	client_t *				clients;

	ENetHost				*server;//server socket
} serverStatic_t;

// ============================================================================

extern serverActive_t		sv;
extern serverStatic_t		svs;

extern cvar_t *		sv_serverId;
extern cvar_t *		sv_protocol;
extern cvar_t *		sv_hostName;
extern cvar_t *		sv_map;
extern cvar_t *		sv_nextMap;
extern cvar_t *		sv_pure;
extern cvar_t *		sv_fps;
extern cvar_t *		sv_numClients;
extern cvar_t *		sv_maxClients;
extern cvar_t *		sv_maxRate;
extern cvar_t *		sv_reconnectLimit;

void				SV_SpawnServer (const char *levelName);

void				SV_SendReliableCommand (client_t *client, const char *fmt, ...);
void				SV_BroadcastReliableCommand (const char *fmt, ...);

void				SV_DropClient (client_t *client, const char *reason);
void				SV_UserInfoChanged (client_t *client);

void				SV_ParseClientMessage (client_t *client, ByteBuffer *msg);

void				SV_SendPacketToClient (client_t *client, bool force);
void				SV_SendClientPackets (void);

void				SV_Map_f (void);
void				SV_DevMap_f (void);
void				SV_NextMap_f (void);
void				SV_KillServer_f (void);
void				SV_ServerStatus_f (void);
void				SV_ServerInfo_f (void);
void				SV_DumpUserInfo_f (void);
void				SV_KickClient_f (void);
void				SV_KickPlayer_f (void);
void				SV_KickAll_f (void);

/*
 ==============================================================================

 INTERFACE TO GAME LIBRARY

 ==============================================================================
*/

extern sgExport_t *			sg;

void				SG_Init (void);
void				SG_Shutdown (void);


#endif	// __SERVER_H__
